package com.zh.user.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.zh.common.annotation.NeedAuth;
import com.zh.common.annotation.NeedPermission;
import com.zh.common.annotation.NeedRoles;
import com.zh.common.annotation.Operator;
import com.zh.common.constant.AuthConstant;
import com.zh.common.dto.IpDto;
import com.zh.common.properties.JwtProperties;
import com.zh.user.domain.dto.BanUserDto;
import com.zh.user.domain.dto.UpdateUserDto;
import com.zh.user.service.UserService;
import com.zh.web.base.ApiResult;
import com.zh.web.base.BaseController;
import com.zh.web.base.PageApiResult;
import com.zh.web.domain.auth.dto.AddRole2UserDto;
import com.zh.web.domain.auth.dto.DelRole2UserDto;
import com.zh.web.domain.auth.dto.PageUserDto;
import com.zh.web.domain.auth.dto.UserDto;
import com.zh.web.domain.auth.entity.User;
import com.zh.web.domain.auth.vo.UserVo;
import com.zh.web.openApi.AuthClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Collection;
import java.util.List;
import java.util.Set;

@Api(tags = "用户管理接口")
@Slf4j
@RequestMapping("/user")
@RequiredArgsConstructor
@RestController
@Validated
@Operator
public class UserController extends BaseController {

    private final UserService userService;
    private final JwtProperties jwtProperties;
    private final AuthClient authClient;

    @ApiOperationSupport(order = 10)
    @GetMapping("/getUserInfoByToken")
    @ApiOperation(value = "根据token获取登录用户信息")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "Authorization", value = "Bearer token", required = true, dataType = "string", paramType = "header")
    )
    public ApiResult<UserVo> getUserInfoByToken(HttpServletRequest request) {
        return buildSuccessPackage(userService.getUserInfoByToken(request.getHeader(jwtProperties.getTokenName())));
    }

    @PostMapping("/getInfo")
    @ApiOperation(value = "id/username获取用户信息（Vo）为用户展示信息")
    public ApiResult<UserVo> getUserInfo(@RequestBody UserDto userDto, HttpServletRequest request) {
        IpDto ipAddress = getIpAddress(request);
        UserVo userInfo = userService.getUserInfo(userDto);
        userInfo.setIpInfo(ipAddress);
        return buildSuccessPackage(userInfo);
    }

    @PostMapping("/getUser")
    @ApiOperation(value = "id/username获取用户信息（登陆时，系统内部调用）", hidden = true)
    public ApiResult<User> getUser(@RequestBody UserDto userDto) {
        return buildSuccessPackage(userService.getUser(userDto));
    }

    @GetMapping("/getUserCount")
    @ApiOperation(value = "获取用户数量，注册时，系统内部调用", hidden = true)
    public ApiResult<Integer> getUserCount() {
        return buildSuccessPackage(userService.getUserCount());
    }

    @PostMapping
    @ApiOperation(value = "新增用户",hidden = true)
    public ApiResult<Long> addUser(@RequestBody User user) {
        user.setCreateOperator(operator);
        user.setUpdateOperator(operator);
        return buildSuccessPackage(userService.addUser(user));
    }

    /**
     * 修改用户信息
     *
     * @param updateUserDto 修改用户信息实体
     * @return Boolean 是否修改成功
     * @throws Exception
     */
    @PutMapping
    @NeedAuth(roles = {@NeedRoles(value = {AuthConstant.USER})})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "Bearer token", required = true, dataType = "string", paramType = "header")
    })
    @ApiOperation(value = "修改用户信息")
    public ApiResult<String> updateUserInfo(@RequestBody UpdateUserDto updateUserDto, HttpServletRequest request) throws Exception {
        updateUserDto.setUpdateOperator(operator);
        return buildSuccessPackage(userService.updateUser(updateUserDto, request));
    }

    @PostMapping("/page")
    @NeedAuth(roles = {@NeedRoles(value = {AuthConstant.ADMIN})}, permissions = {@NeedPermission(value = {AuthConstant.SELECT})})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "Bearer token", required = true, dataType = "string", paramType = "header")
    })
    @ApiOperation(value = "分页查询用户，管理员/select", notes = "管理端用")
    public ApiResult<PageApiResult<UserVo>> pageUser(@RequestBody PageUserDto pageUserDto) {
        return buildSuccessPackage(userService.pageUser(pageUserDto));
    }

    @PostMapping("/role2User/add")
    @ApiOperation(value = "添加角色到用户,需要管理员或者insert")
    @NeedAuth(roles = {@NeedRoles(value = AuthConstant.ADMIN)}, permissions = {@NeedPermission(value = AuthConstant.INSERT)})
    @ApiImplicitParams(
            @ApiImplicitParam(name = "Authorization", value = "Bearer token", required = true, dataType = "string", paramType = "header")
    )
    public ApiResult<String> addRole2User(@Valid @RequestBody AddRole2UserDto addRole2UserDto) {
        return buildMsgPackage(authClient.addRole2User(addRole2UserDto).getMsg());
    }

    @DeleteMapping("/role2User/delete")
    @ApiOperation(value = "删除用户拥有角色,需要管理员或者delete")
    @NeedAuth(roles = {@NeedRoles(value = AuthConstant.ADMIN)}, permissions = {@NeedPermission(value = AuthConstant.DELETE)})
    @ApiImplicitParams(
            @ApiImplicitParam(name = "Authorization", value = "Bearer token", required = true, dataType = "string", paramType = "header")
    )
    public ApiResult<String> delRole2User(@RequestBody DelRole2UserDto delRole2UserDto) {
        delRole2UserDto.setCreateOperator(operator);
        delRole2UserDto.setUpdateOperator(operator);
        return buildMsgPackage(authClient.delRole2User(delRole2UserDto).getMsg());
    }
    @PutMapping("/ban")
    @ApiOperation(value = "封禁用户,需要管理员或者update")
    @NeedAuth(roles = {@NeedRoles(value = AuthConstant.ADMIN)}, permissions = {@NeedPermission(value = AuthConstant.UPDATE)})
    @ApiImplicitParams(
            @ApiImplicitParam(name = "Authorization", value = "Bearer token", required = true, dataType = "string", paramType = "header")
    )
    public ApiResult<String> banUser(@Valid @RequestBody BanUserDto banUserDto){
        banUserDto.setCreateOperator(operator);
        banUserDto.setUpdateOperator(operator);
        return buildMsgPackage(userService.banUser(banUserDto));
    }

    @PostMapping("/list")
    @ApiOperation(value = "ids获取用户列表",hidden = true)
    public ApiResult<List<UserVo>> listUser(@RequestBody Collection<Long> userIds){
        return buildSuccessPackage(userService.list(userIds));
    }
}
